﻿using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Runtime.Serialization.Formatters.Binary;

namespace JYH.Framework
{
    /// <summary>
    /// 系统安全类：加（解）密&&（反）序列化
    /// </summary>
    public class Security
    {
        private static string key_string = "JYH20140307shenhxliangjf";  //加密密钥
        private static string iv_string = "12345678";   //初始化向量    
        private static byte[] key;
        private static byte[] iv;

        /// <summary>
        /// 初始化iv与key
        /// (简单加密算法)
        /// </summary>
        private static void InitKeyAndIV()
        {
            key = System.Text.Encoding.ASCII.GetBytes(key_string);
            iv = System.Text.Encoding.ASCII.GetBytes(iv_string);
        }



        /// <summary>
        /// 加密算法
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string Encrypt(string data)
        {
            if (key == null || iv == null)
                InitKeyAndIV();
            byte[] _data = System.Text.Encoding.UTF8.GetBytes(data);    //如果使用Unicode编码，支持中文加密
            var result = string.Empty;
            using (MemoryStream ms = new MemoryStream())
            {
                TripleDESCryptoServiceProvider _3des = new TripleDESCryptoServiceProvider();
                using (CryptoStream cs = new CryptoStream(ms, _3des.CreateEncryptor(key, iv), CryptoStreamMode.Write))
                {
                    cs.Write(_data, 0, _data.Length);
                    cs.FlushFinalBlock();
                    result = Convert.ToBase64String(ms.ToArray());
                }
            }
            return result;
        }

        /// <summary>
        /// 解密算法
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string Decrypt(string data)
        {
            if (key == null || iv == null)
                InitKeyAndIV();
            var result = string.Empty;
            byte[] encrypted_data = Convert.FromBase64String(data);
            using (MemoryStream ms = new MemoryStream())
            {
                TripleDESCryptoServiceProvider _3des = new TripleDESCryptoServiceProvider();
                using (CryptoStream cs = new CryptoStream(ms, _3des.CreateDecryptor(key, iv), CryptoStreamMode.Write))
                {
                    cs.Write(encrypted_data, 0, encrypted_data.Length);
                    cs.FlushFinalBlock();
                    result = System.Text.Encoding.UTF8.GetString(ms.ToArray());
                }
            }
            return result;
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string EncryptMD5(string str)
        {
            MD5CryptoServiceProvider md = new MD5CryptoServiceProvider();
            byte[] b = ASCIIEncoding.ASCII.GetBytes(str.Trim());
            return ASCIIEncoding.ASCII.GetString(md.ComputeHash(b));
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str">加密字符</param>
        /// <param name="code">加密位数16/32</param>
        /// <returns></returns>
        public static string MD5(string str, int code)
        {
            string strEncrypt = string.Empty;
            if (code == 16)
            {
                strEncrypt = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").Substring(8, 16);
            }
            if (code == 32)
            {
                strEncrypt = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
            }

            return strEncrypt;
        }

        /// <summary>
        /// 序列化对象对文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="person"></param>
        public void Serialization(string fileName, string login)
        {
            using (FileStream writer = new FileStream(fileName, FileMode.Create))
            {
                System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                formatter.Serialize(writer, login);
            }
        }

        /// <summary>
        /// 从序列化文件中重建对象
        /// </summary>
        public string UnSerialization(string fileName)
        {
            using (FileStream reader = new FileStream(fileName, FileMode.Open))
            {
                System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                return (string)formatter.Deserialize(reader);
            }
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns>序列化对象后的字符串</returns>
        public static string SerializeObject<T>(T obj)
        {
            System.Runtime.Serialization.IFormatter bf = new BinaryFormatter();
            string result = string.Empty;
            using (MemoryStream ms = new System.IO.MemoryStream())
            {
                bf.Serialize(ms, obj);
                byte[] byt = new byte[ms.Length];
                byt = ms.ToArray();
                result = System.Convert.ToBase64String(byt);
                ms.Flush();
            }
            return result;
        }

        /// <summary>
        /// 还原序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns>T对象</returns>
        public static T DeserializeObject<T>(string str) where T : class
        {
            System.Runtime.Serialization.IFormatter bf = new BinaryFormatter();
            byte[] byt = Convert.FromBase64String(str);
            using (MemoryStream ms = new MemoryStream(byt, 0, byt.Length))
            {
                return (T)bf.Deserialize(ms);
            }
        }

        #region MyRegion

        #region ========加密========
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string DESEncrypt(string Text)
        {
            return DESEncrypt(Text, "JYH");
        }
        /// <summary> 
        /// 加密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string DESEncrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray;
            inputByteArray = Encoding.Default.GetBytes(Text);
            des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            return ret.ToString();
        }

        #endregion

        #region ========解密========
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string DESDecrypt(string Text)
        {
            return DESDecrypt(Text, "JYH");
        }
        /// <summary> 
        /// 解密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string DESDecrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            int len;
            len = Text.Length / 2;
            byte[] inputByteArray = new byte[len];
            int x, i;
            for (x = 0; x < len; x++)
            {
                i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                inputByteArray[x] = (byte)i;
            }
            des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return Encoding.Default.GetString(ms.ToArray());
        }

        #endregion

        #endregion
    }
}
